package com.scidpro;

import java.util.List;

import net.robotmedia.billing.BillingController;
import net.robotmedia.billing.BillingRequest.ResponseCode;
import net.robotmedia.billing.helper.AbstractBillingObserver;
import net.robotmedia.billing.model.Transaction;
import net.robotmedia.billing.model.Transaction.PurchaseState;

import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.scidpro.util.Book;
import com.scidpro.util.DownloadBookTask;

public class BookDescriptionActivity extends Activity {

	public static abstract class MyAbstractBillingObserver extends AbstractBillingObserver {

		protected static final String KEY_TRANSACTIONS_RESTORED_TIME = "com.scidpro.transactionsRestoredTime";
		protected static final long TEN_MINUTES = 10 * 60 * 1000;

		public MyAbstractBillingObserver(Activity activity) {
			super(activity);
		}

		public boolean isTransactionsRestored() {
			final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
			boolean restored = preferences.getBoolean(KEY_TRANSACTIONS_RESTORED, false);
			if (restored) {
				long now = System.currentTimeMillis();
				long when = preferences.getLong(KEY_TRANSACTIONS_RESTORED_TIME, 0);
				return now - when < TEN_MINUTES;
			} else {
				return false;
			}
		}

		@Override
		public void onTransactionsRestored() {
			final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
			final Editor editor = preferences.edit();
			editor.putBoolean(KEY_TRANSACTIONS_RESTORED, true);
			editor.putLong(KEY_TRANSACTIONS_RESTORED_TIME, System.currentTimeMillis());
			editor.commit();
		}

	}

	private static final int DIALOG_BILLING_NOT_SUPPORTED_ID = 2;

	private MyAbstractBillingObserver mBillingObserver;

	private Book book;

	private TextView bookTitle;
	private TextView bookDescription;
	private TextView bookPrice;

	private ProgressBar loadingBar;
	private TextView googlePlayNotAvailableNotification;
	private Button buyButton;
	private Button downloadButton;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.book_description);

		bookTitle = (TextView) findViewById(R.id.book_title);
		bookDescription = (TextView) findViewById(R.id.book_description);
		bookPrice = (TextView) findViewById(R.id.book_price);

		bookTitle.setText("Book Title");

		if (getIntent().getExtras().containsKey("book")) {
			book = (Book) getIntent().getSerializableExtra("book");

			if (book != null) {
				if (book.name != null && book.name.trim().length() > 0) {
					setTitle(book.name);
					bookTitle.setText(book.name);
				}
				if (book.description != null && book.description.trim().length() > 0) {
					bookDescription.setText(Html.fromHtml(book.description));
					bookDescription.setMovementMethod(LinkMovementMethod.getInstance());
				} else {
					bookDescription.setVisibility(View.GONE);
				}
				if (book.price != null && book.price.trim().length() > 0) {
					bookPrice.setText(book.price.toUpperCase());
				} else {
					bookPrice.setVisibility(View.GONE);
				}
			}
		}

		loadingBar = (ProgressBar) findViewById(R.id.loading_bar);
		googlePlayNotAvailableNotification = (TextView) findViewById(R.id.google_play_not_available_notification);

		buyButton = (Button) findViewById(R.id.buy_button);
		buyButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				String sku = book.id;
				BillingController.requestPurchase(BookDescriptionActivity.this, sku, true /* confirm */);
			}
		});

		downloadButton = (Button) findViewById(R.id.download_button);
		downloadButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				new DownloadBookTask(BookDescriptionActivity.this, book).execute();
			}
		});

		if (book != null) {
			if ("free".equals(book.price.toLowerCase())) {
				showDownloadButton(true);
			} else {
				mBillingObserver = new MyAbstractBillingObserver(this) {
					@Override
					public void onBillingChecked(boolean supported) {
						BookDescriptionActivity.this.onBillingChecked(supported);
					}

					@Override
					public void onPurchaseStateChanged(String itemId, PurchaseState state) {
						BookDescriptionActivity.this.onPurchaseStateChanged(itemId, state);
					}

					@Override
					public void onRequestPurchaseResponse(String itemId, ResponseCode response) {
						BookDescriptionActivity.this.onRequestPurchaseResponse(itemId, response);
					}

					@Override
					public void onTransactionsRestored() {
						super.onTransactionsRestored();
						BookDescriptionActivity.this.onTransactionsRestored();
					}
				};

				showLoadingBar();
				BillingController.registerObserver(mBillingObserver);
				BillingController.checkBillingSupported(this);
			}
		} else {
			showGooglePlayNotAvailableNotification();
		}
	}

	@Override
	protected void onDestroy() {
		if (mBillingObserver != null) {
			BillingController.unregisterObserver(mBillingObserver);
		}
		super.onDestroy();
	}

	/**
	 * Restores previous transactions, if any. This happens if the application
	 * has just been installed or the user wiped data. We do not want to do this
	 * on every startup, rather, we want to do only when the database needs to
	 * be initialized.
	 */
	private void restoreTransactions() {
		if (!mBillingObserver.isTransactionsRestored()) {
			BillingController.restoreTransactions(this);
			Toast.makeText(this, R.string.restoring_transactions, Toast.LENGTH_LONG).show();
		} else {
			onTransactionsRestored();
		}
	}

	public void onBillingChecked(boolean supported) {
		if (supported) {
			showBuyButton(false);
			restoreTransactions();
		} else {
			showDialog(DIALOG_BILLING_NOT_SUPPORTED_ID);
			showGooglePlayNotAvailableNotification();
		}
	}

	public void onPurchaseStateChanged(String itemId, PurchaseState state) {
	}

	public void onRequestPurchaseResponse(String itemId, ResponseCode response) {
		System.out.println("itemId:" + itemId + " ResponseCode:" + response);
	}

	public void onTransactionsRestored() {
		boolean own = false;

		List<Transaction> transactions = BillingController.getTransactions(this);
		for (Transaction t : transactions) {
			if (t.purchaseState == PurchaseState.PURCHASED && t.productId.equals(book.id)) {
				own = true;
				break;
			}
		}

		if (own) {
			showDownloadButton(true);
		} else {
			showBuyButton(true);
		}
	}

	private void showLoadingBar() {
		show(0, true);
	}

	private void showGooglePlayNotAvailableNotification() {
		show(1, true);
	}

	private void showBuyButton(boolean enable) {
		show(2, enable);
	}

	private void showDownloadButton(boolean enable) {
		show(3, enable);
	}

	private void show(int what, boolean enable) {
		loadingBar.setVisibility(View.GONE);
		googlePlayNotAvailableNotification.setVisibility(View.GONE);
		buyButton.setVisibility(View.GONE);
		downloadButton.setVisibility(View.GONE);

		switch (what) {
		case 0:
			loadingBar.setVisibility(View.VISIBLE);
			break;
		case 1:
			googlePlayNotAvailableNotification.setVisibility(View.VISIBLE);
			break;
		case 2:
			buyButton.setVisibility(View.VISIBLE);
			buyButton.setEnabled(enable);
			break;
		case 3:
			downloadButton.setVisibility(View.VISIBLE);
			downloadButton.setEnabled(enable);
			break;
		}
	}

}
